package com.yunxiao.cloud.generator.component;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;

import java.util.ArrayList;
import java.util.List;

/**
 * @description: 代码生成器
 * @author: yunxiao
 * @date: 2020/1/8 13:44
 * @version: V1.0
 **/
public class MyGenerator {

    private static final String TABLE_PREFIX = "tb_";

    public static void main(String[] args) {
        MyGenerator g = new MyGenerator();
        boolean startWithI = false;
        String projectName = "C:\\yunxiao\\workspace\\yunxiao-cloud\\yunxiao-cloud-dwgenerator";
        String packageName = "com.yunxiao.cloud.dwgenerator";
        String[] tableName = {"dw_connection_manage"
        };
        g.generateByTables(startWithI, projectName, packageName,
                tableName);
    }

    /**
     * 配置数据源
     *
     * @return
     */
    private DataSourceConfig getDataSourceConfig() {
        return new DataSourceConfig().setDbType(DbType.POSTGRE_SQL)
                .setUrl("jdbc:postgresql://localhost:5432/postgres")
                .setUsername("postgres")
                .setPassword("root")
                .setDriverName("org.postgresql.Driver");
    }

    /**
     * 根据表自动生成
     *
     * @param serviceNameStartWithI 默认为false
     * @param packageName           包名
     * @param tableNames            表名
     */
    private void generateByTables(boolean serviceNameStartWithI,
                                  String projectName,
                                  String packageName,
                                  String... tableNames) {
        //配置数据源
        DataSourceConfig dataSourceConfig = getDataSourceConfig();
        // 策略配置
        StrategyConfig strategyConfig = getStrategyConfig(tableNames);
        //全局变量配置
        GlobalConfig globalConfig = getGlobalConfig(serviceNameStartWithI, projectName);
        //包名配置
        PackageConfig packageConfig = getPackageConfig(packageName);

        InjectionConfig injectionConfig = getInjectionConfig(projectName);
        //自动生成
        autoGenerator(dataSourceConfig, strategyConfig, globalConfig, packageConfig, injectionConfig);
    }

    /**
     * 集成
     *
     * @param dataSourceConfig 配置数据源
     * @param strategyConfig   策略配置
     * @param config           全局变量配置
     * @param packageConfig    包名配置
     */
    private void autoGenerator(DataSourceConfig dataSourceConfig,
                               StrategyConfig strategyConfig,
                               GlobalConfig config,
                               PackageConfig packageConfig,
                               InjectionConfig injectionConfig) {
        AutoGenerator mpg = new AutoGenerator();

        mpg.setGlobalConfig(config);
        mpg.setDataSource(dataSourceConfig);
        mpg.setStrategy(strategyConfig);
        mpg.setPackageInfo(packageConfig);
        mpg.setCfg(injectionConfig);
        mpg.setTemplate(new TemplateConfig().setXml(null));
        mpg.setTemplateEngine(new VelocityTemplateEngine());
        mpg.execute();
    }

    /**
     * 设置包名
     *
     * @param packageName
     * @return
     */
    private PackageConfig getPackageConfig(String packageName) {
        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent(packageName);
        pc.setMapper("mapper");
        pc.setController("controller");
        pc.setService("service");
        pc.setEntity("entity");
        return pc;
    }

    private InjectionConfig getInjectionConfig(String projectName) {
        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectName + "/src/main/resources/mapper/"
                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        cfg.setFileOutConfigList(focList);

        return cfg;
    }

    /**
     * 全局配置
     *
     * @param serviceNameStartWithI
     * @param projectName
     * @return
     */
    private GlobalConfig getGlobalConfig(boolean serviceNameStartWithI, String projectName) {
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setBaseColumnList(true)
                .setSwagger2(true)
                .setBaseResultMap(true)
                .setActiveRecord(false)
                .setAuthor("yunxiao")
                //设置输出路径
                .setOutputDir(projectName + "/src/main/java/")
                .setFileOverride(true);
        if (!serviceNameStartWithI) {
            //设置service名
            globalConfig.setServiceName("%sService");
        }
        return globalConfig;
    }

    /**
     * 策略配置
     *
     * @param tableNames
     * @return
     */
    private StrategyConfig getStrategyConfig(String... tableNames) {
        return new StrategyConfig()
                // 全局大写命名 ORACLE 注意
                .setCapitalMode(true)
                .setRestControllerStyle(false)
                .setTablePrefix(TABLE_PREFIX)
                //从数据库表到文件的命名策略
                .setNaming(NamingStrategy.underline_to_camel)
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setEntityLombokModel(false)
                //需要生成的的表名，多个表名传数组
                .setInclude(tableNames);
    }
}
